﻿using System;
using System.IO;
using System.IO.IsolatedStorage;

namespace Jok.Client.Infrastructure
{
    public class ISManager
    {
        private const long INSCREEZE_SIZE = 1024 * 1024 * 10; // 10 MB

        private string GetAddress(DirectoryType Type, string Name)
        {
            return String.Concat(Type, "/", Name);
        }
        public bool CheckAvailableMemory(long SizeNeeded)
        {
            using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                long inscreezeSize = INSCREEZE_SIZE * ((SizeNeeded / INSCREEZE_SIZE) + 1);

                if (SizeNeeded > storage.AvailableFreeSpace)
                {
                    long newSize = storage.Quota + inscreezeSize;

                    return (storage.IncreaseQuotaTo(newSize));
                }

                return true;
            }
        }

        public IsolatedStorageFileStream ReadStream(string Name)
        {
            return ReadStream(DirectoryType.Other, Name);
        }
        public IsolatedStorageFileStream ReadStream(DirectoryType Type, string Name)
        {
            Stream result = new MemoryStream();
            string address = GetAddress(Type, Name);

            using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!storage.FileExists(address))
                    return null;

                return storage.OpenFile(address, FileMode.Open, FileAccess.Read);
            }
        }

        public bool SaveStream(string Name, Stream Package)
        {
            return SaveStream(DirectoryType.Other, Name, Package);
        }
        public bool SaveStream(DirectoryType Type, string Name, Stream Package)
        {
            if (!CheckAvailableMemory(Package.Length))
                return false;

            using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
            using (var fileStream = new IsolatedStorageFileStream(GetAddress(Type, Name), FileMode.Create, storage))
            {
                Package.CopyTo(fileStream);

                return true;
            }
        }

        public void DeleteStream(string Name)
        {
            DeleteStream(DirectoryType.Other, Name);
        }
        public void DeleteStream(DirectoryType Type, string Name)
        {
            using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!storage.FileExists(GetAddress(Type, Name)))
                    return;

                storage.DeleteFile(GetAddress(Type, Name));
            }
        }

        public string[] GetFileNames()
        {
            return GetFileNames(DirectoryType.Other);
        }
        public string[] GetFileNames(DirectoryType Type)
        {
            CreateDirectories();

            using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                string s = String.Concat(Type, "/*");
                return storage.GetFileNames(s);
            }
        }

        private void CreateDirectories()
        {
            using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                for (int i = 0; i < 2; i++)
                {
                    if (!storage.DirectoryExists(((DirectoryType)i).ToString()))
                        storage.CreateDirectory(((DirectoryType)i).ToString());
                }
            }
        }

        public bool Exists(string Name)
        {
            return Exists(DirectoryType.Other, Name);
        }
        public bool Exists(DirectoryType Type, string Name)
        {
            using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                return storage.FileExists(GetAddress(Type, Name));
            }
        }
    }

    public enum DirectoryType
    {
        Packages,
        Other
    }
}
